package testjeu;

import java.awt.Font;
//import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Random;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.TrueTypeFont;
import org.newdawn.slick.particles.ParticleIO;
import org.newdawn.slick.particles.ParticleSystem;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class Fin extends BasicGameState implements Constantes {

	private ParticleSystem feu[]=new ParticleSystem[3];
	private double[] feuX=new double[3];
	private double[] feuY=new double[3];
	private double[] feuT=new double[3];
	private double[] feuD=new double[3];
	
	private int[] feuDestX=new int[3];
	private int[] feuDestY=new int[3];
	private int[] feuDiffX=new int[3];
	private int[] feuDiffY=new int[3];
	private int[] feuDebX =new int[3];
	private int[] feuDebY =new int[3];
	
	private double x1, y1, temps1, durée1;
	private int xDest1, yDest1, xDiff1, yDiff1, xDeb1, yDeb1; 

	private double x2, y2, temps2, durée2;
	private int xDest2, yDest2, xDiff2, yDiff2, xDeb2, yDeb2; 	
	
	
	private TrueTypeFont verdana;
	
	@Override
	public int getID() {
		return ID_fin;
	}

	@Override
	public void init(GameContainer container, StateBasedGame game) throws SlickException {
		try {
			for (int i=0;i<3;i++) {
				feu[i]=ParticleIO.loadConfiguredSystem("res/artifice"+(i+1)+".xml");
				feuX[i]=feuDebX[i]=feuDestX[i]=400;
				feuY[i]=feuDebY[i]=feuDestY[i]=400;
				feuD[i]=500; feuT[i]=0;
			}
		} catch (IOException e) {
			throw new SlickException("Failed to load particle systems", e);
		}
		
		
		x1=xDeb1=xDest1=200;
		y1=yDeb1=yDest1=200;
		durée1=1500; temps1=0;
		
		x2=xDeb2=xDest2=200;
		y2=yDeb2=yDest2=400;
		durée2=1500; temps2=0;
		
		Font font = new Font("Verdana",Font.PLAIN, 40);
		verdana = new TrueTypeFont(font, true);
	}
	
	@Override
	public void enter(GameContainer container, StateBasedGame game) throws SlickException {

		container.setTargetFrameRate(300);
		
		// Ecrire le log dans fichier txt
		if(1==1) {
			
				/*FileWriter f = new FileWriter("log.html");
				f.write("<br /><br /><hr />"+Jeu.log);
				f.close();*/
				System.out.println("Envoie du log");

				try {
					URL url = new URL(URL_LOG+"?log="+URLEncoder.encode(Jeu.log, "ISO-8859-1"));
					URLConnection uc = url.openConnection();
					InputStream in = uc.getInputStream(); 
					if (in.read()!=-1) 	System.out.println("Envoie log terminé avec succés !");
					else 	   			System.out.println("Erreur !");
					
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}

		
		}
		


	}

	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
	
		for (int i=0; i<3;i++) {
			feu[i].render((float)feuX[i], (float)feuY[i]);
		}
		
		verdana.drawString((int)x1,(int)y1, "!! Objectif atteint !!", Color.black);
		verdana.drawString((int)x1-2,(int)y1-2, "!! Objectif atteint !!", Color.yellow);
		
		verdana.drawString((int)x2,(int)y2, "Score : 1234", Color.black);
		verdana.drawString((int)x2-2,(int)y2-2, "Score : 1234", Color.white);
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
		
		// Les feux
		for (int i=0;i<3;i++) {
			feu[i].update(delta);
			if (feuT[i]>feuD[i]+100) {
				feuDestX[i]=new Random().nextInt(550)+100;
				feuDestY[i]=new Random().nextInt(550)+100;
				feuDebX[i]=(int)feuX[i];
				feuDebY[i]=(int)feuY[i];
				feuD[i]=1100+new Random().nextInt(150);
				feuT[i]=0;
				feuDiffX[i]=(int)(feuDestX[i]-feuX[i]);
				feuDiffY[i]=(int)(feuDestY[i]-feuY[i]);
			}
			
			feuX[i]=easeInSine (feuT[i], feuDebX[i], feuDiffX[i], feuD[i]);
			feuY[i]=easeInSine (feuT[i], feuDebY[i], feuDiffY[i], feuD[i]);			
		
			feuT[i]+=delta;	
			
		}
		
		// 1 = Texte de fin
		if (temps1>durée1+100) {
			xDest1=new Random().nextInt(550);
			yDest1=new Random().nextInt(650);
			xDeb1=(int)x1;
			yDeb1=(int)y1;
			durée1=2100;
			temps1=0;
			xDiff1=(int)(xDest1-x1);
			yDiff1=(int)(yDest1-y1);
		}

		x1=easeOutBounce(temps1, xDeb1, xDiff1, durée1);
		y1=easeOutBounce(temps1, yDeb1, yDiff1, durée1);					
	
		temps1+=delta;
		
		// 2 = Score
		if (temps2>durée2+200) {
			xDest2=new Random().nextInt(550);
			yDest2=new Random().nextInt(650);
			xDeb2=(int)x2;
			yDeb2=(int)y2;
			durée2=1200;
			temps2=0;
			xDiff2=(int)(xDest2-x2);
			yDiff2=(int)(yDest2-y2);
		}

		x2=easeOutExp (temps2, xDeb2, xDiff2, durée2);
		y2=easeOutExp (temps2, yDeb2, yDiff2, durée2);					
	
		temps2+=delta;		
		
	}

	

	private double easeOutBounce (double t, int b, int c, double d){
		t/=1000; d/=1000;
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	}
	
	private double easeOutExp (double t, int b, int c, double d){
		t/=1000; d/=1000;
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	}
	
	@SuppressWarnings("unused")
	private double easeInOutQuint (double t, int b, int c, double d){
		t/=1000; d/=1000;
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	}

	@SuppressWarnings("unused")
	private double 	easeOutElastic(double t, int b, int c, double d){
		double s=1.70158;
		double p=0;
		double a=c;
		t/=1000; d/=1000;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (p==0) p=d*.3;
		if (a < Math.abs(c)) { a=c; s=p/4; }
		else s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	}
	
	
	
	private double 	easeInSine(double t, int b, int c, double d){
		d/=1000; t/=1000;
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	}


	
	
	
}
